package cn.tedu.charging.device.service.impl;

import cn.tedu.chaging.common.pojo.vo.StationInfoVO;
import cn.tedu.charging.device.service.StationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.BoundGeoOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class StationServiceImpl implements StationService {

    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;


    @Override
    public List<StationInfoVO> getNearByStation(Double longitude, Double latitude, Double radius) {
        //通过redisTemplate 创建操作GEO的 操作工具类
        BoundGeoOperations<String, Serializable> stations = redisTemplate.boundGeoOps("stations");
        //通过redisTemplate 创建操作Hash的 操作工具类
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        //通过用户位置的经纬度创建redis的位置对象 Point
        Point point = new Point(longitude,latitude);
        //通过用户传入的查找距离订单距离对象 Distance
        Distance distance = new Distance(radius, Metrics.KILOMETERS);
        //通过点对象和距离对象创建圈 饼
        Circle circle = new Circle(point,distance);
        //设置参数
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        //设置redis返回距离
        args.includeDistance();
        //设置redis返回坐标 经纬度
        args.includeCoordinates();
        //通过操作GEO的工具类查询附近的充电站,返回站的id和距离信息和坐标信息
        GeoResults<RedisGeoCommands.GeoLocation<Serializable>> results = stations.radius(circle,args);
        log.debug("通过经度:{} 纬度:{}距离:{} 结果:{}",longitude,latitude,distance,results);
        //循环遍历返回的结果
        List<StationInfoVO> resultVos = new ArrayList<>();
        for (GeoResult<RedisGeoCommands.GeoLocation<Serializable>> result : results) {
            //获取站的id
            Serializable name = result.getContent().getName();
            //获取站的和我的位置的距离
            double stationDistance = result.getDistance().getValue();
            //获取站经纬度 Point
            Point stationPoint = result.getContent().getPoint();
            Integer stationId = Integer.valueOf(String.valueOf(name));
            String bigKey = String.valueOf(name);
            String hashKey = "name";
            //通过大key 站点id 和 hash-key 详情的属性 name 获取小map里具体的值
            Object nameValue = hashOperations.get(bigKey, hashKey);
            log.debug("通过大key:{} 和 hash-key:{} 获取小map里具体的值:{}",name,hashKey,nameValue);
            //通过大key 站点id 获取小map所有的值
            Map<Object, Object> entries = hashOperations.entries(bigKey);
            log.debug("通过大key:{}获取小map里所有的值:{}",name,entries);
            Object deviceNumberObj = entries.get("deviceNumber");
            Object codeObj = entries.get("code");
            Object nameObj = entries.get("name");
            //Object longObj = entries.get("longitude");
            //Object latObj = entries.get("latitude");
            //封装返回结果对象并且设置值
            StationInfoVO stationInfoVO = new StationInfoVO();
            //设置距离
            stationInfoVO.setDistance(stationDistance);
            stationInfoVO.setStationId(stationId);
            stationInfoVO.setStationCode(String.valueOf(codeObj));
            stationInfoVO.setStationName(String.valueOf(nameObj));
            stationInfoVO.setDeviceNumber(Integer.valueOf(String.valueOf(deviceNumberObj)));
            //设置经度
            stationInfoVO.setLongitude(stationPoint.getX());
            //设置维度
            stationInfoVO.setLatitude(stationPoint.getY());
            resultVos.add(stationInfoVO);
        }
        return resultVos;
    }
}
